Skip to content

feat(nextjs): Add support for Next.js 16 cache components#7595

Open
jacekradko wants to merge 11 commits intomainfrom
feat/nextjs-cache-components-support
Open

feat(nextjs): Add support for Next.js 16 cache components#7595
jacekradko wants to merge 11 commits intomainfrom
feat/nextjs-cache-components-support

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Jan 14, 2026

Summary

Adds support for Next.js 16 cache components by improving error detection and providing helpful error messages when auth() or currentUser() are called inside a "use cache" function.

Changes

  • Add ClerkUseCacheError class with symbol marker to prevent double-wrapping of error messages
  • Add isNextjsUseCacheError() helper to detect "use cache" context errors with tightened regex patterns to reduce false positives
  • Add isClerkUseCacheError() helper to identify already-formatted Clerk errors
  • Update buildRequestLike() to throw ClerkUseCacheError with helpful message
  • Update auth() and currentUser() to check for already-formatted errors before wrapping
  • Update clerkClient() to re-throw ClerkUseCacheError
  • Add unit tests for error detection and handling

Problem

When a developer calls auth() or currentUser() inside a "use cache" function, they receive a cryptic error about headers() not being allowed in cache contexts.

Solution

Detect these errors and provide a helpful message with a code example showing the correct pattern:

Clerk: auth() and currentUser() cannot be called inside a "use cache" function.
These functions access `headers()` internally, which is a dynamic API not allowed in cached contexts.

To fix this, call auth() outside the cached function and pass the values you need as arguments:

  async function getCachedUser(userId: string) {
    "use cache";
    const client = await clerkClient();
    return client.users.getUser(userId);
  }

  // In your component/page:
  const { userId } = await auth();
  if (userId) {
    const user = await getCachedUser(userId);
  }

Implementation details

  • Uses a custom ClerkUseCacheError class with a symbol marker to prevent double-wrapping when errors bubble through multiple catch handlers (buildRequestLikeauthcurrentUser)
  • Tightened regex patterns in isNextjsUseCacheError() to reduce false positives - now requires specific Next.js error patterns like "use cache" combined with headers/cookies context

Test plan

  • Unit tests for ClerkUseCacheError, isClerkUseCacheError(), isNextjsUseCacheError(), and isPrerenderingBailout()
  • Integration tests for cache components
  • Build succeeds
  • All tests pass

How to verify

Setup

  1. Create or use a Next.js 16 app with cache components enabled:

    // next.config.ts
    import type { NextConfig } from 'next'
    
    const nextConfig: NextConfig = {
      cacheComponents: true, // No longer under experimental in Next.js 16
    }
    
    export default nextConfig
  2. Install the PR preview package:

    npm i https://pkg.pr.new/@clerk/nextjs@7595

Test the error detection

Create a page that calls auth() inside a "use cache" function:

// app/test-cache/page.tsx
import { auth } from '@clerk/nextjs/server';

async function getCachedData() {
  "use cache";
  const { userId } = await auth(); // This should trigger our helpful error
  return { userId };
}

export default async function TestPage() {
  const data = await getCachedData();
  return <div>{JSON.stringify(data)}</div>;
}

Expected behavior

Before this PR: Cryptic Next.js error about headers() not being allowed in cache contexts

After this PR: Clear error message explaining the issue and showing the correct pattern

- Add `isNextjsUseCacheError()` helper to detect "use cache" context errors
- Update `isPrerenderingBailout()` to detect cache component prerendering errors
- Update `buildRequestLike()` to provide helpful error message with code example
  when auth() is called inside a "use cache" function
- Update `clerkClient()` to re-throw "use cache" errors
- Add unit tests for error detection helpers
@changeset-bot
Copy link

changeset-bot bot commented Jan 14, 2026

🦋 Changeset detected

Latest commit: 3404ed3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
clerk-js-sandbox Skipped Skipped Feb 4, 2026 7:22pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

Adds detection and handling for Next.js 16 "use cache" component errors across the Clerk Next.js package. Introduces ClerkUseCacheError, isClerkUseCacheError, isNextjsUseCacheError, regex patterns, and USE_CACHE_ERROR_MESSAGE. Integrates these into server utils, request construction, clerkClient, auth, and currentUser to rethrow or wrap matched errors. Adds unit tests for the helpers, integration pages and an API route demonstrating correct/incorrect "use cache" patterns, and a changeset documenting the capability.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(nextjs): Add support for Next.js 16 cache components' directly and accurately summarizes the main objective of the PR, which is to add support for Next.js 16 cache components with improved error detection and clearer error messaging.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 14, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7595

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7595

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7595

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7595

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7595

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7595

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7595

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7595

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7595

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7595

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7595

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7595

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7595

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7595

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7595

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7595

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7595

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7595

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7595

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7595

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7595

commit: 3404ed3

Wrap auth() and currentUser() in try-catch to catch "use cache" errors
that bubble up from the Next.js cache boundary. The original
implementation only caught errors inside buildRequestLike(), but Next.js
throws these errors at a higher level.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/nextjs/src/app-router/server/auth.ts`:
- Around line 138-143: The catch block in auth.ts re-wraps Next.js "use cache"
errors that buildRequestLike() already formats, causing duplicate messages;
update the catch in the function containing isNextjsUseCacheError(e) to first
detect if the thrown error is already formatted (e.g., check if e.message
startsWith or equals USE_CACHE_ERROR_MESSAGE or if a marker property exists) and
only re-wrap when it is not already formatted, or remove the catch entirely and
rely on buildRequestLike(); reference isNextjsUseCacheError, buildRequestLike,
and USE_CACHE_ERROR_MESSAGE when making the change.

- Add currentUser() server component test page and tests
- Add currentUser() with "use cache" correct pattern page
- Add error trigger page that calls auth() inside "use cache"
- Add test verifying Clerk's custom error message is shown
- Add signed-out state tests for cache and PPR pages
- Update home page navigation with new test links
- Add ClerkUseCacheError class with symbol marker to identify already-formatted errors
- Update auth() and currentUser() to check for ClerkUseCacheError before wrapping
- Tighten isNextjsUseCacheError() regex to reduce false positives
- Update clerkClient.ts to use isClerkUseCacheError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants